package com.oracle.usercf;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;


public class Job2 {
	public static class Map extends Mapper<LongWritable, Text, Text, Text> {
		@Override
		protected void map(LongWritable key, Text value, Context context)
				throws IOException, InterruptedException {
			String line = value.toString();
			String split[] = line.split("\t");
			
			String item;
			String user = split[0];
			String val;
			double M = 0;
			
			for(int i = 1; i < split.length; i++) {
				M += Math.pow(Double.parseDouble(split[i].substring(split[i].indexOf("_")+1)), 2);
			}
			
			for(int i = 1; i < split.length; i++) {
				item = split[i].substring(0, split[i].indexOf("_"));
				val = split[i].substring(split[i].indexOf("_")+1);
				context.write(new Text(item), new Text(user+"_"+val));
				context.write(new Text(item), new Text("M_"+user+"_"+M));
			}
		}
	}
	
	public static class Reduce extends Reducer<Text, Text, Text, Text> {
		@Override
		protected void reduce(Text key, Iterable<Text> values, Context context)
				throws IOException, InterruptedException {
			List<String> line = new ArrayList<>();
			for(Text i: values) {
				line.add(i.toString());
			}
			
			List<String> list = new ArrayList<>();
			HashMap<String, String> map = new HashMap<>();
			for(String i: line) {
				if(i.startsWith("M")) {
					map.put(i.substring(i.indexOf("_")+1, i.lastIndexOf("_")), i);
				}else {
					list.add(i);
				}
			}
			
			String item1;
			String item2;
			double val1;
			double val2;
			
			for(String i: list) {
				item1 = i.substring(0, i.indexOf("_"));
				val1 = Double.parseDouble(i.substring(i.indexOf("_")+1));
				for(String j: list) {
					item2 = j.substring(0, j.indexOf("_"));
					val2 = Double.parseDouble(j.substring(j.indexOf("_")+1));
					context.write(new Text(item1+","+item2+"_"+(val1*val2)), new Text(map.get(item1)+"\t"+map.get(item2)));
				}
			}
		}
		
	}
	
	public static void main(String[] args) throws Exception {

		Configuration conf = new Configuration();
		
		Job job = Job.getInstance(conf);
		job.setJarByClass(Job2.class);
		job.setMapperClass(Map.class);
		job.setReducerClass(Reduce.class);
		
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(Text.class);
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);
		
		FileInputFormat.setInputPaths(job, new Path("/usercf/output1"));
		FileOutputFormat.setOutputPath(job, new Path("/usercf/output2"));
		
		job.waitForCompletion(true);
	
	}
}
